package com.yh.controller;

import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author: yh
 * @date: 2020/11/1 18:31
 * @code: 愿世间永无Bug!
 * @description: 文件上传与下载 (伪下载 文件读写的过程)
 * 上传：文件前端传入，后端获取到文件通过输出流写入文件
 * 下载：获取到文件路径，通过输入流读取，在通过输出流写入文件实现下载
 * <p>
 * 真正实现文件上传服务器（使用ftp协议 文件传输协议 网络访问传输协议）
 * 也可以获取项目的相对路径在项目下（项目部署在了服务器上）创建一个文件夹用于保存文件，上传的文件保存在项目路径下即可（还可以将路径保存到数据库中http://localhost:8080/file/XXX）
 * 下载的话：前端文件名展示，指定文件下载获取到文件名，找到路径进行文件读取写入到客户端
 */
@Slf4j  //lombok提供的日志注解可直接调用 log的方法
@Controller
@RequestMapping("/file")
public class FileUploadController {

    /**
     * 上传图片到本地磁盘
     *
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/uploadimg")
    @ResponseBody
    public Map<String, Object> uploadImg(@RequestParam("image") MultipartFile file) throws IOException {
        //得到上传文件的后缀名
        String sub1 = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        System.out.println(sub1);

        String sub2 = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
        System.out.println(sub2);

        String randomName = UUID.randomUUID().toString().split("-")[0];
        Map<String, Object> map = new HashMap<>();
        //保存文件到本地磁盘,注意,一定需要文件的路径和名字
        try {
            file.transferTo(new File("C:\\Users\\master\\Pictures\\" + randomName + sub1));
            map.put("message", "upload success");
        } catch (IOException e) {
            e.printStackTrace();
            map.put("message", e.getMessage());
        } catch (IllegalStateException e) {
            e.printStackTrace();
            map.put("message", e.getMessage());
        }
        return map;
    }

    @PostMapping("/uploadfile")
    @ResponseBody
    public Map<String, Object> uploadFile(@RequestParam("image") MultipartFile file) throws IOException {
        String name = file.getOriginalFilename();
        Map<String, Object> map = new HashMap<>();
        //保存文件到本地磁盘,注意,一定需要文件的路径和名字
        try {
            file.transferTo(new File("C:\\Users\\master\\Pictures\\" + name));
            map.put("message", "upload success");
        } catch (IOException e) {
            e.printStackTrace();
            map.put("message", e.getMessage());
        } catch (IllegalStateException e) {
            e.printStackTrace();
            map.put("message", e.getMessage());
        }
        return map;
    }

    /**
     * 下载本地磁盘文件
     * @param fileName
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @GetMapping("/download")
    public String download(String fileName
            , HttpServletRequest request
            , HttpServletResponse response) throws IOException {
        String filePath = "C:\\Users\\master\\Pictures\\" + fileName;
        //通过流读取文件
        InputStream is = new FileInputStream(new File("C:\\Users\\master\\Pictures\\" + fileName));
        File file = new File(filePath);
        //设置响应头信息
        if (file.exists()) {
            response.setContentType("application/octet-stream");
            response.setHeader("content-type", "application/octet-stream");
            response.setHeader("content-disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));
        }
        //得到输出流
        ServletOutputStream os = response.getOutputStream();
        //使用工具类
        try {
            IOUtils.copy(is, os);
            request.setAttribute("message", "upload success");
        } catch (IOException e) {
            e.printStackTrace();
            request.setAttribute("message", e.getMessage());
        }
        //通过响应流将文件输入流读取到的文件写出
        IOUtils.closeQuietly(os);
        IOUtils.closeQuietly(is);
        return "index";
    }
}